import React, { Component } from 'react'

// 1. 字符串形式的ref(控制台报警告, 不推荐使用)
export class RefStringDemo extends Component {

  // 展示左侧输入框的数据
  showData = () => {
    // 实例对象上有refs
    const { input1 } = this.refs
    alert(input1.value)
  }

  // 展示右侧输入框的数据
  showData2 = () => {
    const { input2 } = this.refs
    alert(input2.value)
  }

  render() {
    return (
      <div>
        <input ref="input1" type="text" placeholder="点击按钮提示数据" />&nbsp;
        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
        <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
      </div>
    )
  }
}

// 2. 回调形式的ref
export class RefCallbackDemo extends Component {

  state = { isHot: true }

  changeWeather = () => {
    //获取原来的状态
    const { isHot } = this.state
    //更新状态
    this.setState({ isHot: !isHot })
  }

  //展示左侧输入框的数据
  showData = () => {
    const { input1 } = this
    alert(input1.value)
  }
  //展示右侧输入框的数据
  showData2 = () => {
    const { input2 } = this
    alert(input2.value)
  }

  // 避免ref的回调函数反复调用, 不要写成内联函数
  saveInput = (currentNode) => {
    this.input3 = currentNode
    console.log('组件更新时不再调用:', currentNode)
  }

  showData3 = () => {
    const { input3 } = this
    alert(input3.value)
  }

  render() {
    const { isHot } = this.state
    return (
      <div>
        <h2>今天天气很{isHot ? '炎热' : '凉爽'}</h2>
        <button onClick={this.changeWeather}>点我切换天气</button><br /><br />
        {/* 因为写了ref React自动调用了回调函数 执行次数? 当以内联函数定义时, 在更新过程中会被执行两次, 第一次传入null, 第二次才是真正的节点 */}
        <input ref={(currentNode) => { this.input1 = currentNode; console.log(currentNode) }} type="text" placeholder="点击按钮提示数据" />&nbsp;
        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
        <input onBlur={this.showData2} ref={c => this.input2 = c} type="text" placeholder="失去焦点提示数据" />&nbsp;
        <hr />
        {/* 通过将ref的回调函数定义成class的绑定函数的方式可以避免问题 */}
        <input ref={this.saveInput} type="text" onBlur={this.showData3} />
      </div>
    )
  }
}

// 3. createRef(React最为推荐的形式)
export class RefCreateRefDemo extends Component {
  /* 
    React.createRef调用后可以返回一个容器, 该容器可以存储被ref所标识的节点, 该容器是“专人专用”的
  */

  /* 
    (1).通过onXxx属性指定事件处理函数(注意大小写)
      a.React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 —————— 为了更好的兼容性
      b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) ————————为了的高效
    (2).通过event.target得到发生事件的DOM元素对象 ——————————不要过度使用ref
 */
  myRef = React.createRef()
  // myRef2 = React.createRef()
  //展示左侧输入框的数据
  showData = () => {
    alert(this.myRef.current.value);
  }
  //展示右侧输入框的数据
  showData2 = (event) => {
    // alert(this.myRef2.current.value);
    alert(event.target.value)
  }
  render() {
    return (
      <div>
        <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />&nbsp;
        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
        <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据" />&nbsp;
      </div>
    )
  }
}